Added initial documentation tree using doxygen. More tweaks on the license text ensur...
[lwes-dotnet/github-mirror.git] / Test Projects / Org.Lwes.Tests / StatusTests.cs
blobafb12a964d7e15dd39d68f9b3a47aa6f44e9554a
1 namespace Org.Lwes.Tests
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Text;
7 using System.Threading;
9 using Microsoft.VisualStudio.TestTools.UnitTesting;
11 /// <summary>
12 /// Summary description for StatusTests
13 /// </summary>
14 [TestClass]
15 public class StatusTests
17 #region Enumerations
19 enum TestStates
21 Default = 0,
22 On = 2,
23 Off = 3,
24 Undecided = 4,
25 ShutdownSignaled = 5,
26 OnStateDone = 6,
27 OffStateDone = 7,
28 Done = 8
31 #endregion Enumerations
33 #region Properties
35 public TestContext TestContext
37 get; set;
40 #endregion Properties
42 #region Methods
44 [TestMethod]
45 public void TestParallelStateTransitions()
47 // The intention here is to cause maximum contention on the Status<> class's methods
48 // and thereby provide sufficient confidence that the class provides non-blocking,
49 // thread-safe state transitions.
50 var control = new
52 NumberOfThreadsPerState = 10,
53 WaitPulseMilliseconds = 200,
54 MainThreadWaitTimeBeforeShutdown = TimeSpan.FromSeconds(10)
57 Status<TestStates> state = new Status<TestStates>(default(TestStates));
58 int onThreadsStarted = 0;
59 int offThreadsStarted = 0;
60 int undecidedThreadsStarted = 0;
62 int transitionsOn = 0;
63 int transitionsOff = 0;
64 int transitionsUndecided = 0;
65 int transitionsOnStateDone = 0;
66 int transitionsOffStateDone = 0;
67 int transitionsDone = 0;
69 for (int i = 0; i < control.NumberOfThreadsPerState; i++)
71 // These background jobs transition the state from TestStates.Undecided
72 // to TestStates.On - when successful it increments transitionsOn.
73 ThreadPool.QueueUserWorkItem(new WaitCallback((unused_state) =>
75 state.SpinWaitForState(TestStates.Undecided, () => Thread.Sleep(control.WaitPulseMilliseconds));
76 Interlocked.Increment(ref onThreadsStarted);
77 while (state.IsLessThan(TestStates.ShutdownSignaled))
79 state.TryTransition(TestStates.On, TestStates.Undecided, () =>
81 Interlocked.Increment(ref transitionsOn);
82 });
84 state.TryTransition(TestStates.OnStateDone, TestStates.ShutdownSignaled, () =>
86 Interlocked.Increment(ref transitionsOnStateDone);
87 });
88 }));
89 // These background jobs transition the state from TestStates.On
90 // to TestStates.Off - when successful it increments transitionsOff.
91 ThreadPool.QueueUserWorkItem(new WaitCallback((unused_state) =>
93 state.SpinWaitForState(TestStates.On, () => Thread.Sleep(control.WaitPulseMilliseconds));
94 Interlocked.Increment(ref offThreadsStarted);
96 while(state.IsLessThan(TestStates.OnStateDone))
98 state.TryTransition(TestStates.Off, TestStates.On, () =>
100 Interlocked.Increment(ref transitionsOff);
103 state.TryTransition(TestStates.OffStateDone, TestStates.OnStateDone, () =>
105 Interlocked.Increment(ref transitionsOffStateDone);
107 }));
108 // These background jobs transition the state from TestStates.Off
109 // to TestStates.Undecided - when successful it increments transitionsUndecided.
110 ThreadPool.QueueUserWorkItem(new WaitCallback((unused_state) =>
112 state.SpinWaitForState(TestStates.Off, () => Thread.Sleep(control.WaitPulseMilliseconds));
113 Interlocked.Increment(ref undecidedThreadsStarted);
115 while (state.IsLessThan(TestStates.OffStateDone))
117 state.TryTransition(TestStates.Undecided, TestStates.Off, () =>
119 Interlocked.Increment(ref transitionsUndecided);
123 state.TryTransition(TestStates.Done, TestStates.OffStateDone, () =>
125 Interlocked.Increment(ref transitionsDone);
127 }));
130 // Signal the first group of threads that they should start.
131 state.SetState(TestStates.Undecided);
133 // Wait the prescribed amount of time...
134 Thread.Sleep(control.MainThreadWaitTimeBeforeShutdown);
135 // Signal the shutdown...
136 state.SetState(TestStates.ShutdownSignaled);
137 // Wait for background threads to shutdown...
138 state.SpinWaitForState(TestStates.Done, () => Thread.Sleep(control.WaitPulseMilliseconds));
140 Assert.IsTrue(Thread.VolatileRead(ref transitionsOn) >= Thread.VolatileRead(ref transitionsOff));
141 Assert.IsTrue(Thread.VolatileRead(ref transitionsOff) >= Thread.VolatileRead(ref transitionsUndecided));
142 Assert.AreEqual(1, Thread.VolatileRead(ref transitionsOnStateDone));
143 Assert.AreEqual(1, Thread.VolatileRead(ref transitionsOffStateDone));
144 Assert.AreEqual(1, Thread.VolatileRead(ref transitionsDone));
146 Console.WriteLine(String.Concat("Threads transitioninig to On: ", onThreadsStarted, ", transitions = ", transitionsOn));
147 Console.WriteLine(String.Concat("Threads transitioninig to Off: ", offThreadsStarted, ", transitions = ", transitionsOff));
148 Console.WriteLine(String.Concat("Threads transitioninig to Undecided: ", undecidedThreadsStarted, ", transitions = ", transitionsUndecided));
151 #endregion Methods